package com.example.optional;

import com.example.Employee;
import org.junit.Test;

import java.util.Optional;

//011
/*
 * Optional<T>类（java.util.Optional）是一个容器类，代表一个值存在或者不存在，原来用null表示一个值不存在，现在Optional可以更友好的表达这个概念。并且可以避免空指针一场。
 * Optional容器类的常用方法：
 *  Optional.of(T t)：创建一个Optional实例
 *  Optional.empty()：创建一个空的Optional实例
 *  Optional.ofNullable(T t)：若t不为null，创建Optional实例，否则创建空实例
 *  isPresent()：判断是否包含值
 *  orElse(T t)：如果调用对象包含值，返回该值，否则返回t
 *  orElseGet(Supplier s)：如果调用对象包含值，返回该值，否则返回s获取的值
 *  map(Function f)：如果有值对其处理，并返回处理后的Optional，否则返回Optional.empty()
 *  flatMap(Function mapper)：与map类似，要求返回值必须是Optional，进一步避免空指针
 */
public class TestOptional {
    //Optional.of(T t)：创建一个Optional实例
    @Test
    public void test1() {
        Optional<Employee> op = Optional.of(new Employee());
        Employee employee = op.get();
        System.out.println(employee);
    }

    //Optional.empty()：创建一个空的Optional实例
    @Test
    public void test2() {
        Optional<Employee> empty = Optional.empty();
        System.out.println(empty.get());
    }


    //Optional.ofNullable(T t)：若t不为null，创建Optional实例，否则创建空实例
    //isPresent()：判断是否包含值
    //orElse(T t)：如果调用对象包含值，返回该值，否则返回t
    //orElseGet(Supplier s)：如果调用对象包含值，返回该值，否则返回s获取的值
    @Test
    public void test3() {
        Optional<Employee> employee = Optional.ofNullable(null);
        if (employee.isPresent())
            System.out.println(employee.get());
        Employee employee1 = employee.orElse(new Employee("zhangsan", 18, 123.1));
        System.out.println(employee1);

        Employee employee2 = employee.orElseGet(() -> new Employee("lisi", 32, 333.3));
        System.out.println(employee2);
    }

    //map(Function f)：如果有值对其处理，并返回处理后的Optional，否则返回Optional.empty()
    //flatMap(Function mapper)：与map类似，要求返回值必须是Optional，进一步避免空指针
    @Test
    public void test4() {
        Optional<Employee> employee = Optional.ofNullable(new Employee("张三", 18, 9999.99, Employee.Status.FREE));
        Optional<String> name = employee.map((emp) -> emp.getName());
        System.out.println(name.get());
        Optional<String> name2 = employee.flatMap((emp) -> Optional.of(emp.getName()));
        System.out.println(name2.get());
    }

    //例题
    @Test
    public void test5() {
        Man man = new Man();
        try {
            String name = getGodnessName(man);
            System.out.println(name);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String name1 = getGodnessName1(man);
        System.out.println(name1);

        Optional<NewMan> op = Optional.of(new NewMan());
        String name2 = getGodnessName2(op);
        System.out.println(name2);
    }

    //需求：获取一个男人心中女神的名字
    public String getGodnessName(Man man) {
        return man.getGodness().getName();
    }

    //传统方式
    public String getGodnessName1(Man man) {
        if (null != man) {
            Godness godness = man.getGodness();
            if (null != godness) {
                return godness.getName();
            }
        }
        return "哈哈哈";
    }

    //Optional
    public String getGodnessName2(Optional<NewMan> man) {
        return man.orElse(new NewMan())
                .getGodness()
                .orElse(new Godness("嘿嘿"))
                .getName();
    }

}
